package math

import (
	"jvm/nzpJvm/instructions/base"
	"jvm/nzpJvm/runtime_area"
)

// 移位指令

//int 左移
type ISHL struct {
	base.NoOperandsInstruction
}
// int算术右移
type ISHR struct {
	base.NoOperandsInstruction
}
// int逻辑右移
type IUSHR struct {
	base.NoOperandsInstruction
}
// long左移
type LSHL struct {
	base.NoOperandsInstruction
}
// long算术右移
type LSHR struct {
	base.NoOperandsInstruction
}
// long逻辑右移
type LUSHR struct {
	base.NoOperandsInstruction
}

func (self *ISHL)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	// 栈顶值是移动的位数
	moveCount := stack.PopInt()
	// 要左移的int值
	popInt := stack.PopInt()
	u := uint32(moveCount) & 0x1f // 只取后五位，因为int移位不能超过32位
	result := popInt << u
	stack.PushInt(result)

}

func (self *ISHR)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	// 栈顶值是移动的位数
	moveCount := stack.PopInt()
	// 要左移的int值
	popInt := stack.PopInt()
	u := uint32(moveCount) & 0x1f // 只取后五位，因为移位不能超过32
	result := popInt << u

	stack.PushInt(int32(result))
}

func (self *IUSHR)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	// 栈顶值是移动的位数
	moveCount := stack.PopInt()
	// 要左移的int值
	popInt := stack.PopInt()
	u := uint32(moveCount) & 0x1f // 只取后五位，因为移位不能超过32
	result := uint32(popInt) << u
	// GO里面没有无符号右移指令，只能先转成无符号数，再转回来
	stack.PushInt(int32(result))
}

func (self *LSHL)Execute(frame *runtime_area.Frame){
    stack := frame.OperandStack()
	moveCount := stack.PopInt()
	popLong := stack.PopLong()
	u := uint32(moveCount) & 0x3f
	result := popLong << u
	stack.PushLong(result)
}

func (self *LSHR)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	moveCount := stack.PopInt()
	popLong := stack.PopLong()
	u := uint32(moveCount) & 0x3f
	result := popLong >> u
	stack.PushLong(result)
}

func (self *LUSHR)Execute(frame *runtime_area.Frame){
	stack := frame.OperandStack()
	moveCount := stack.PopInt()
	popLong := stack.PopLong()
	u := uint32(moveCount) & 0x3f
	result := uint64(popLong) >> u
	stack.PushLong(int64(result))
}